package v1

import (
	"github.com/gin-gonic/gin"
	"io"
	"net/http"
	"pay/bll"
	"pay/model"
	"pay/server/web/middleware"
	"pay/utils"
)

var FeePlan = &feePlan{}

func init() {
	RegisterRouter(FeePlan)
}

type feePlan struct{}

// Init
func (a *feePlan) Init(r *gin.RouterGroup) {
	g := r.Group("/feePlan", middleware.Auth())
	{
		g.POST("/create", a.create)
		g.POST("/update", a.update)
		g.POST("/list", a.list)
		g.POST("/delete", a.delete)
		g.POST("/detail", a.find)
	}

	appG := r.Group("app/feePlan", middleware.Auth())
	{
		appG.POST("/list", a.appListFeePlan)
		appG.POST("/pay/prepay", a.appPrePay)
		appG.POST("/pay/result", a.appPayResult)
		//appG.POST("/applePay/verify", a.applePayVerify)
	}

	callbackG := r.Group("/callback")
	{
		callbackG.POST("/wx/notify", a.wxPayNotify)
		callbackG.POST("/ali/notify", a.aliPayNotify)
		callbackG.POST("/ali/receiveSignNotify", a.receiveSignNotify)
	}
}

// create
func (a *feePlan) create(c *gin.Context) {
	var (
		in  = &model.FeePlanCreateRequest{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		_ = c.Error(err)
		return
	}

	if err = bll.FeePlan.Create(c.Request.Context(), in); err != nil {
		_ = c.Error(err)
		return
	}
	utils.ResponseOk(c, nil)
}

// update
func (a *feePlan) update(c *gin.Context) {
	var (
		in  = &model.FeePlanUpdateRequest{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		_ = c.Error(err)
		return
	}

	if err = bll.FeePlan.Update(c.Request.Context(), in); err != nil {
		_ = c.Error(err)
		return
	}
	utils.ResponseOk(c, nil)
}

// list
func (a *feePlan) list(c *gin.Context) {
	var (
		in  = &model.FeePlanListRequest{}
		out = &model.FeePlanListResponse{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		_ = c.Error(err)
		return
	}

	if out, err = bll.FeePlan.List(c.Request.Context(), in); err != nil {
		_ = c.Error(err)
		return
	}
	utils.ResponseOk(c, out)
}

// appListFeePlan
func (a *feePlan) appListFeePlan(c *gin.Context) {
	var (
		in  = &model.AppListFeePlanRequest{}
		out = &model.AppListFeePlanResponse{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		_ = c.Error(err)
		return
	}

	if out, err = bll.FeePlan.AppListFeePlan(c.Request.Context(), in); err != nil {
		_ = c.Error(err)
		return
	}
	utils.ResponseOk(c, out)
}

// appPrePay
func (a *feePlan) appPrePay(c *gin.Context) {
	var (
		in  = &model.AppPrePayRequest{}
		out = &model.AppPrePayResponse{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		_ = c.Error(err)
		return
	}

	if out, err = bll.FeePlan.AppPrePay(c.Request.Context(), in); err != nil {
		_ = c.Error(err)
		return
	}
	utils.ResponseOk(c, out)
}

// appPayResult
func (a *feePlan) appPayResult(c *gin.Context) {
	var (
		in  = &model.AppPayResultRequest{}
		out = &model.AppPayResultResponse{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		_ = c.Error(err)
		return
	}

	if out, err = bll.FeePlan.AppPayResult(c.Request.Context(), in); err != nil {
		_ = c.Error(err)
		return
	}
	utils.ResponseOk(c, out)
}

// applePayVerify
func (a *feePlan) applePayVerify(c *gin.Context) {
	var (
		in  = &model.AppPrePayRequest{}
		out = &model.AppPrePayResponse{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		_ = c.Error(err)
		return
	}

	if out, err = bll.FeePlan.AppPrePay(c.Request.Context(), in); err != nil {
		_ = c.Error(err)
		return
	}
	utils.ResponseOk(c, out)
}

// list
func (a *feePlan) find(c *gin.Context) {
	var (
		in  = &model.FeePlanInfoRequest{}
		out = &model.FeePlanInfo{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		_ = c.Error(err)
		return
	}

	if out, err = bll.FeePlan.Find(c.Request.Context(), in); err != nil {
		_ = c.Error(err)
		return
	}
	utils.ResponseOk(c, out)
}

// delete
func (a *feePlan) delete(c *gin.Context) {
	var (
		in  = &model.FeePlanDeleteRequest{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		_ = c.Error(err)
		return
	}

	if err = bll.FeePlan.Delete(c.Request.Context(), in); err != nil {
		_ = c.Error(err)
		return
	}
	utils.ResponseOk(c, nil)
}

// wxPayNotify
func (a *feePlan) wxPayNotify(c *gin.Context) {

	var (
		in          = &model.WxPayNotifyRequest{}
		err         error
		contextCopy = c.Copy()
		failResp    = func(msg string) map[string]string {
			return map[string]string{"code": "FAIL", "message": msg}
		}
	)

	if err = contextCopy.ShouldBindJSON(in); err != nil {
		_ = c.Error(err)
		return
	}

	if err = c.ShouldBindHeader(&in.ReqHeaders); err != nil {
		c.JSON(http.StatusBadRequest, failResp("bad request header"))
		return
	}

	//执行读取Body的操作
	bs, err := io.ReadAll(c.Request.Body)
	if err != nil {
		c.JSON(http.StatusBadRequest, failResp("bad request body"))
		return
	}

	in.RequestBody = bs

	if n, e := bll.FeePlan.WxPayNotify(c.Request.Context(), in); e != nil {
		c.JSON(n, failResp(e.Error()))
		return
	}

	c.String(http.StatusOK, "")
}

func (a *feePlan) aliPayNotify(c *gin.Context) {

	in := &model.AliPayNotifyRequest{
		Request: c.Request,
	}

	n, err := bll.FeePlan.AliPayNotify(c.Request.Context(), in)
	if err != nil {
		c.JSON(n, err.Error())
		return
	}

	c.String(http.StatusOK, "success")
}

func (a *feePlan) receiveSignNotify(c *gin.Context) {

	in := &model.ReceiveSignNotifyRequest{
		Request: c.Request,
	}

	n, err := bll.FeePlan.ReceiveSignNotify(c.Request.Context(), in)
	if err != nil {
		c.JSON(n, err.Error())
		return
	}

	c.String(http.StatusOK, "success")
}
